/*
 * Copyright (c) 2018-present, lmyooyo@gmail.com.
 *
 * This source code is licensed under the GPL license found in the
 * LICENSE file in the root directory of this source tree.
 */
package com.zhg.videorecord.collect

import android.graphics.ImageFormat
import android.graphics.Rect
import android.hardware.Camera
import android.util.Log
import com.zhg.videorecord.entity.CodecContext
import com.zhg.videorecord.helper.CodectUtil
import com.zhg.videorecord.helper.TLog

/**
 * desc:封装一些camera的api 设置相关
 */
class CameraHelper {
    companion object {
        private val printParam=true;
        private val TAG="相机参数-"
        fun getNumberOfCameras(): Int {
            return Camera.getNumberOfCameras()
        }
        /**
         * 摄像头支持多种分辨率，选择某一组
         */
        fun setPreviewSize(cameraParam: Camera.Parameters, context: CodecContext) {
            val supportSizes = cameraParam.supportedPreviewSizes

            var suportBestWidth = 0
            var suportBestHeight = 0
            for (size in supportSizes) {
                if (printParam){
                    TLog.i(TAG+"支持分辨率:${size.width}x${size.height}")
                }
                if (size.width >= context.video.height//预览宽大于输出宽
                        && size.height >= context.video.width//预览高大于输出高
                        && (size.width * size.height < suportBestWidth * suportBestHeight || 0 == suportBestWidth * suportBestHeight)) {//选择像素最少的分辨率
                    suportBestWidth = size.width
                    suportBestHeight = size.height
                }else{
                    //
                    suportBestWidth = 1920
                    suportBestHeight = 1080
                }
            }
            context.cameraSize.width = suportBestWidth
            context.cameraSize.height = suportBestHeight
            context.check()
            TLog.i(TAG+"期望分辨率: " + context.video.width + "x" + context.video.width + ",实际设置：" + suportBestWidth + "x" + suportBestHeight)
            cameraParam.setPreviewSize(context.cameraSize.width, context.cameraSize.height)
        }

        fun setColorFormat(cameraParam: Camera.Parameters, context: CodecContext) {
            if (printParam){
                for (i in cameraParam.supportedPreviewFormats){
                    TLog.i(TAG+"支持色彩空间："+CodectUtil.getImageFormatName(i))
                }
            }

            if (cameraParam.supportedPreviewFormats.contains(ImageFormat.NV21))
                cameraParam.previewFormat = ImageFormat.NV21
            TLog.i(TAG+"实际设置色彩空间：NV21")

        }

        fun setFocusMode(cameraParam: Camera.Parameters, context: CodecContext) {
            val modes = cameraParam.supportedFocusModes ?: return
            if (printParam){
                for (i in cameraParam.supportedFocusModes){
                    TLog.i(TAG+"支持对焦模式："+i)
                }
            }
            when {
                modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO) -> cameraParam.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
                modes.contains(Camera.Parameters.FOCUS_MODE_AUTO) -> cameraParam.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
                modes.contains(Camera.Parameters.FOCUS_MODE_FIXED) -> cameraParam.focusMode = Camera.Parameters.FOCUS_MODE_FIXED
            }
            TLog.i(TAG+"实际设置对焦模式：${cameraParam.focusMode}")
        }

        fun setFps(cameraParam: Camera.Parameters, context: CodecContext) {
            // 获取所支持的预览帧率范围，每一个组值分别有最大值和最小值，返回的是一个列表，
            // 期望的实际帧率在所设置的帧率范围之内，
            val fpsRanges = cameraParam.supportedPreviewFpsRange
            var fpsRange = IntArray(2)
            cameraParam.getPreviewFpsRange(fpsRange)
            if (context.video.fps > 0) {
                fpsRanges.forEach {
                    if (printParam){
                        TLog.i(TAG+"支持fps:最小=${it[0]},最大${it[1]}")
                    }
                    if (context.video.fps * 1000 >= it[0] && it[0] > fpsRange[0])
                        fpsRange = it
                }
            } else {
                fpsRanges.forEach {
                    if (it[0] != it[1] && Math.abs(it[1] - it[0]) > Math.abs(fpsRange[1] - fpsRange[0])) {
                        fpsRange = it
                    }
                }
            }
            TLog.i(TAG+"期望fps : ${context.video.fps} ，实际设置fps：${(fpsRange[0] + fpsRange[1]) / 2000}")
            context.video.fps = (fpsRange[0] + fpsRange[1]) / 2000
            cameraParam.setPreviewFpsRange(fpsRange[0], fpsRange[1])
        }

        fun setAutoExposureLock(cameraParam: Camera.Parameters, flag: Boolean) {
            if (cameraParam.isAutoExposureLockSupported)
                cameraParam.autoExposureLock = flag
            TLog.i(TAG+"支持自动曝光锁定AutoExposureLock：期望${flag},实际${cameraParam.isAutoExposureLockSupported}")

        }

        fun setSceneMode(cameraParam: Camera.Parameters, mode: String) {
            if (cameraParam.supportedSceneModes != null) {
                if (printParam){
                    for (i in cameraParam.supportedSceneModes){
                        TLog.i(TAG+"支持模式SceneMode:${i}")
                    }
                }
                if ( cameraParam.supportedSceneModes.contains(mode)){
                    cameraParam.sceneMode = mode
                }
                TLog.i(TAG+"期望SceneMode:${mode}，实际${cameraParam.sceneMode}")
            }else{
                TLog.i(TAG+"支持模式SceneMode:空")
            }
        }

        fun setFlashMode(cameraParam: Camera.Parameters, mode: String) {
            if (cameraParam.supportedFlashModes != null && cameraParam.supportedFlashModes.contains(mode)) {
                cameraParam.flashMode = mode
            }
            TLog.i(TAG+"期望FlashMod:${mode}，实际${cameraParam.flashMode}")
        }

        fun setAntibanding(cameraParam: Camera.Parameters, mode: String) {
            if (cameraParam.supportedAntibanding != null && cameraParam.supportedAntibanding.contains(mode)) {
                cameraParam.antibanding = mode
            }
            TLog.i(TAG+"期望Antibanding:${mode}，实际${cameraParam.antibanding}")
        }

        fun setVideoStabilization(cameraParam: Camera.Parameters, flag: Boolean) {
            if (cameraParam.isVideoStabilizationSupported) {
                cameraParam.videoStabilization = flag
            }
            TLog.i(TAG+"期望VideoStabilization:${flag}，实际${cameraParam.videoStabilization}")
        }
        fun setExposureCompensation(cameraParam: Camera.Parameters, value: Int){
            cameraParam.setExposureCompensation(value)
            TLog.i(TAG+"期望ExposureCompensation:${value}，实际${value}")
        }
        fun setWhiteBalance(cameraParam: Camera.Parameters, context: CodecContext){
            if (printParam){
                for (i in cameraParam.getSupportedWhiteBalance() ){
                    TLog.i(TAG+"支持白平衡:${i}")
                }
            }
            if (isSupported(cameraParam.getSupportedWhiteBalance(), "auto")) {
                TLog.i(TAG+"期望白平衡:auto，实际auto")
                cameraParam.setWhiteBalance("auto")
            }
        }
        private fun isSupported(list: List<String>?, key: String): Boolean {
            return list != null && list.contains(key)
        }
        fun setPreviewFormat(cameraParam: Camera.Parameters){
            cameraParam.previewFormat= ImageFormat.NV21
        }
        //----------------------花里胡哨的参数，垃圾摄像头可能不支持------------------
        /**
         *  人脸检测
         */
        fun setFaceDetection(cameraParam: Camera.Parameters,camera:Camera?) {

            // start face detection only *after* preview has started
            if (cameraParam.getMaxNumDetectedFaces() > 0) {
                // camera supports face detection, so can start it:
                camera?.startFaceDetection()
                TLog.i(TAG+"人脸检测：支持")
            }else{
                TLog.i(TAG+"人脸检测：不支持")
            }
        }
        fun setMeteringAreas(cameraParam: Camera.Parameters,camera:Camera?){

            if (cameraParam.getMaxNumMeteringAreas() > 0) {
                TLog.i(TAG+"区域测光：支持")
                // check that metering areas are supported
                val meteringAreas = ArrayList<Camera.Area>()

                val areaRect1 = Rect(-100, -100, 100, 100)    // specify an area in center of image
                meteringAreas.add(Camera.Area(areaRect1, 600)) // set weight to 60%
                val areaRect2 = Rect(800, -1000, 1000, -800)  // specify an area in upper right of image
                meteringAreas.add(Camera.Area(areaRect2, 400)) // set weight to 40%
                cameraParam.setMeteringAreas(meteringAreas)
                camera?.setParameters(cameraParam)

            }else{
                TLog.i(TAG+"区域测光：不支持")
            }

        }
    }
    private fun printAllParam(cameraParam: Camera.Parameters){
        val paramStr = cameraParam.flatten()
        Log.i("",paramStr.replace(";",";\n"))
    }
}